package com.bsdsma.fengheguaiapp.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OpenAiService {

    private static class ApiConstants {
        public static final String OPENAI_API_URL = "https://api.deepseek.com/v1/chat/completions";
        public static final int MAX_RETRIES = 3;
        public static final int RETRY_DELAY_SECONDS = 2;
    }

    private final WebClient webClient;
    private final String secretKey;

    public OpenAiService(WebClient.Builder webClientBuilder,
                         @Value("${openai.secretKey}") String secretKey) {
        this.secretKey = secretKey;
        this.webClient = webClientBuilder
                .baseUrl(ApiConstants.OPENAI_API_URL)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader("Accept", "application/json")
                .build();
    }

    public Flux<String> submitQuestion(String question) {
        if (StringUtils.isEmpty(question)) {
            return Flux.error(new IllegalArgumentException("提问内容不能为空"));
        }

        log.info("Submitting question: {}", question);

        // 构建符合 DeepSeek API 要求的请求体
        Map<String, Object> requestBody = new HashMap<>();
        List<Map<String, String>> messages = new ArrayList<>();

        Map<String, String> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", question);
        messages.add(message);

        requestBody.put("messages", messages);
        requestBody.put("model", "deepseek-chat");  // 指定模型
        requestBody.put("temperature", 0.7);        // 可选参数

        return webClient.post()
                .uri("")
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + secretKey)
                .bodyValue(requestBody)
                .retrieve()
                .onStatus(HttpStatus::is4xxClientError, response ->
                        response.bodyToMono(String.class)
                                .flatMap(error -> {
                                    log.error("Client error: {}", error);
                                    return Mono.error(new RuntimeException("API 客户端错误: " + error));
                                }))
                .onStatus(HttpStatus::is5xxServerError, response ->
                        response.bodyToMono(String.class)
                                .flatMap(error -> {
                                    log.error("Server error: {}", error);
                                    return Mono.error(new RuntimeException("API 服务器错误: " + error));
                                }))
                .bodyToFlux(String.class)
                .map(this::processResponse)
                .retryWhen(Retry.backoff(ApiConstants.MAX_RETRIES,
                                Duration.ofSeconds(ApiConstants.RETRY_DELAY_SECONDS))
                        .filter(this::shouldRetry)
                        .doBeforeRetry(retrySignal ->
                                log.warn("Retrying request. Attempt: {}",
                                        retrySignal.totalRetries() + 1)))
                .onErrorResume(error -> {
                    log.error("Error processing request", error);
                    return Flux.just("处理请求时发生错误: " + error.getMessage());
                })
                .doOnComplete(() -> log.info("Request completed successfully"));
    }

    private boolean shouldRetry(Throwable throwable) {
        // 定义需要重试的异常类型
        return !(throwable instanceof IllegalArgumentException) &&
                !(throwable.getMessage() != null &&
                        throwable.getMessage().contains("API 客户端错误"));
    }

    private String processResponse(String response) {
        log.debug("Processing response: {}", response);

        try {
            JSONObject jsonResponse = JSON.parseObject(response);
            if (jsonResponse.containsKey("choices")) {
                JSONObject choice = jsonResponse.getJSONArray("choices").getJSONObject(0);
                JSONObject message = choice.getJSONObject("message");
                if (message != null && message.containsKey("content")) {
                    String content = message.getString("content");
                    return content.contains("\n")
                            ? content.replace("\n", "<br/>")
                            : content.replace(" ", "&ensp;");
                }
            }
            return "无法解析响应内容";
        } catch (Exception e) {
            log.error("Error processing response: {}", e.getMessage(), e);
            return "处理响应时发生错误: " + e.getMessage();
        }
    }
}